package com.knife.database.backup.utils;

import com.knife.common.constants.BaseConstants;
import com.knife.database.backup.constants.KnifeDialect;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Map;

/**
 * 生成sql语句
 *
 * @author： 76875
 * @date： 2022/3/31 星期四 18:03
 * @description：
 * @modifiedBy：
 * @version: 1.0
 */
public class KnifeSqlUtil {
    //INSERT INTO knife_keep_accounts.expend_details (id, ep_id, ep_money, entry_date, description, tenant_id, object_version_number, creation_date, created_by, last_updated_by, last_update_date, attribute1, attribute2, attribute3, attribute4, attribute5, attribute6, attribute7, attribute8, attribute9, attribute10, attribute11, attribute12, attribute13, attribute14, attribute15) VALUES (530, 48, 640.93, '2022-02-16 08:00:00', '丨趣弹乐器丨-趣弹吉他卡马吉他kepma卡玛民谣初学者女男d1c趣谈音乐学生乐器', 0, 2, '2022-02-20 11:52:42', 100, 100, '2022-02-20 11:52:42', '测试', null, null, null, null, null, null, null, null, null, null, null, null, null, null);


    public static String createInsertSql(KnifeDialect knifeDialect, String tableName, Map<String, Object> map) {
        StringBuffer sb = new StringBuffer("INSERT INTO ");
        sb.append(tableName).append("(");
        sb.append(String.join(",", map.keySet()));
        sb.append(")");
        sb.append(" ").append("VALUES").append(" ").append("(");
        int size = map.size();
        int i = 1;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            Object v = entry.getValue();
            if (v == null) {
                appendNull(sb);
            }
            if (v instanceof Boolean) {
                sb.append((Boolean) v ? 1 : 0);
            } else if (v instanceof Number) {
                sb.append(v.toString());
            } else if (v instanceof CharSequence) {
                String s = v.toString();
                if (s.startsWith("\"") && s.endsWith("\"")) {
                    sb.append(s);
                } else {
                    appendStr(sb, v.toString());
                }
            } else if (v instanceof Date) {
                appendDate(sb, v, knifeDialect);
            } else if (v instanceof LocalDateTime) {
                appendDate(sb, Date.from(((LocalDateTime) v).atZone(ZoneId.systemDefault()).toInstant()), knifeDialect);
            }
            if (i != size) {
                sb.append(",");
            }
            i++;
        }
        sb.append(")").append(";");
        return sb.toString();
    }

    private static StringBuffer appendNull(StringBuffer sb) {
        sb.append("null");
        return sb;
    }


    private static StringBuffer appendStr(StringBuffer sb, String value) {
        sb.append("'").append(value).append("'");
        return sb;
    }

    private static void appendDate(StringBuffer sb, Object v, KnifeDialect knifeDialect) {
        SimpleDateFormat sdf = new SimpleDateFormat(BaseConstants.Pattern.DATETIME);
        if (knifeDialect.equals(KnifeDialect.mysql)) {
            appendStr(sb, sdf.format(v));
        } else if (knifeDialect.equals(KnifeDialect.oracle)) {
            sb.append("TO_DATE(");
            appendStr(sb, sdf.format(v)).append(", 'YYYY-MM-DD HH24:MI:SS')");
        }
    }
}
